﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Urs.Core;
using Urs.Data.Domain.Users;
using Urs.Core.Infrastructure;
using Urs.Data.Domain.Configuration;
using Plugin.Api.Infrastructure;
using Plugin.Api.Models.User;
using Urs.Services.Authentication;
using Urs.Services.Stores;
using Urs.Services.Users;
using Urs.Services.Directory;
using Urs.Services.Localization;
using Urs.Services.Logging;
using Urs.Services.Media;
using Urs.Services.Orders;
using Urs.Framework;
using Urs.Framework.Controllers;

namespace Plugin.Api.Controllers
{
    /// <summary>
    /// 用户信息接口
    /// </summary>
    [ApiAuthorize]
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/user")]
    [ApiController]
    public class UserController : BaseApiController
    {
        private readonly ILocalizationService _localizationService;
        private readonly IWorkContext _workContext;
        private readonly UserSettings _userSettings;
        private readonly RewardPointsSettings _rewardPointsSettings;
        private readonly IUserService _userService;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IUserRegistrationService _userRegistrationService;
        private readonly IAuthenticationService _authenticationService;
        private readonly IActivityLogService _activityLogService;
        private readonly IAreaService _areaService;
        private readonly IOrderTotalCalculationService _orderTotalCalculationService;
        private readonly IPictureService _pictureService;
        private readonly IWebHelper _webHelper;
        private readonly ILogger _logger;
        private readonly MediaSettings _mediaSettings;
        private readonly IUrsFileProvider _fileProvider;

        /// <summary>
        /// 构造器
        /// </summary>
        public UserController(ILocalizationService localizationService,
            IWorkContext workContext,
            UserSettings userSettings,
            RewardPointsSettings rewardPointsSettings,
            IUserService userService,
            IShoppingCartService shoppingCartService,
            IUserRegistrationService userRegistrationService,
            IAuthenticationService authenticationService,
            IActivityLogService activityLogService,
            IAreaService areaService,
            IOrderTotalCalculationService orderTotalCalculationService,
            IPictureService pictureService,
            IWebHelper webHelper,
            ILogger logger,
            MediaSettings mediaSettings,
            IUrsFileProvider fileProvider)
        {
            this._localizationService = localizationService;
            this._workContext = workContext;
            this._userSettings = userSettings;
            this._rewardPointsSettings = rewardPointsSettings;
            this._userService = userService;
            this._shoppingCartService = shoppingCartService;
            this._userRegistrationService = userRegistrationService;
            this._authenticationService = authenticationService;
            this._activityLogService = activityLogService;
            this._areaService = areaService;
            this._orderTotalCalculationService = orderTotalCalculationService;
            this._pictureService = pictureService;
            this._webHelper = webHelper;
            this._logger = logger;
            this._mediaSettings = mediaSettings;
            this._fileProvider = fileProvider;
        }

        [NonAction]
        protected void PrepareMoUserInfo(MoUserInfo model, User user)
        {
            model.Id = user.Id;
            model.Code = user.Code;
            model.Guid = user.UserGuid.ToString();
            model.Nickname = user.Nickname;
            model.Points = user.GetRewardPointsBalance();
            model.AvatarPictureId = user.AvatarPictureId;
            model.AvatarUrl = _pictureService.GetPictureUrl(user.AvatarPictureId, _mediaSettings.AvatarPictureSize, false) ?? string.Empty;
            model.Phone = user.PhoneNumber ?? string.Empty;
            model.Email = user.Email ?? string.Empty;
        }
        /// <summary>
        /// 获取用户信息[简化]
        /// </summary>
        /// <returns></returns>
        [HttpGet("get")]
        public async Task<ApiResponse<MoInfo>> Get()
        {
            var user = RegisterUser;
            if (user == null || user.Deleted)
                return ApiResponse<MoInfo>.Warn("用户不存在");

            var data = await Task.Run(() =>
            {
                var model = new MoInfo();
                model.Id = user.Id;
                model.Nickname = user.Nickname;
                model.Name = user.Nickname;
                model.Guid = user.UserGuid.ToString();
                model.Code = user.Code;
                var roles = user.UserRoles.Select(q => q.Id);
                var roleList = new List<int>();
                if (roles != null)
                {
                    if (roles.Contains(6))
                        roleList.Add(6);
                    if (roles.Contains(7))
                        roleList.Add(7);
                    if (roles.Contains(10))
                        roleList.Add(10);
                    if (roles.Contains(2))
                        roleList.Add(2);
                    if (roles.Contains(3))
                        roleList.Add(3);
                }
                model.RoleIdArray = Newtonsoft.Json.JsonConvert.SerializeObject(roleList);
                if (user.AffiliateId.HasValue)
                {
                    var reffer = _userService.GetUserById(user.AffiliateId.Value);
                    if (reffer != null && reffer.Active)
                    {
                        model.ReferrerCode = reffer.Code;
                        model.ReferrerNickname = reffer.Nickname;
                        model.ReferrerAvatarUrl = _pictureService.GetPictureUrl(reffer.AvatarPictureId, _mediaSettings.AvatarPictureSize, false);
                        if (string.IsNullOrEmpty(model.ReferrerAvatarUrl))
                            model.ReferrerAvatarUrl = reffer.ExternalAuthRecords.Where(q => q.ProviderSystemName == "ExternalAuth.WeixinOpen").Select(q => q.AvatarUrl).FirstOrDefault();
                    }
                }
                model.AvatarPictureId = user.AvatarPictureId;
                model.AvatarUrl = _pictureService.GetPictureUrl(user.AvatarPictureId, _mediaSettings.AvatarPictureSize, false);
                if (string.IsNullOrEmpty(model.AvatarUrl))
                    model.AvatarUrl = user.ExternalAuthRecords.Where(q => q.ProviderSystemName == "ExternalAuth.WeixinOpen").Select(q => q.AvatarUrl).FirstOrDefault();
               
                model.Phone = user.PhoneNumber;
                model.Email = user.Email;


                return model;
            });

            return ApiResponse<MoInfo>.Success(data);
        }
        /// <summary>
        /// 获取用户信息[编辑]
        /// </summary>
        /// <returns></returns>
        [HttpGet("info")]
        public async Task<ApiResponse<MoUserInfo>> GetInfo()
        {
            var user = RegisterUser;
            if (user == null || user.Deleted)
                return ApiResponse<MoUserInfo>.Warn("用户不存在");

            var data = await Task.Run(() =>
            {
                var model = new MoUserInfo();
                PrepareMoUserInfo(model, user);
                return model;
            });

            return ApiResponse<MoUserInfo>.Success(data);
        }
        /// <summary>
        /// 提交用户信息
        /// </summary>
        /// <param name="model">对象</param>
        /// <returns></returns>
        [HttpPost("submit")]
        public async Task<ApiResponse> Submit(MoUserRequest model)

        {
            var user = RegisterUser;

            try
            {
                if (ModelState.IsValid)
                {
                    await Task.Run(() =>
                  {
                      user.Nickname = model.Nickname;
                      if (model.AvatarPictureId > 0)
                          user.AvatarPictureId = model.AvatarPictureId;
                      //save
                      _userService.UpdateUser(user);
                  });
                }

                if (!ModelState.IsValid)
                {
                    return ApiResponse.Warn(ModelState.FirstMessage());
                }

                return ApiResponse.Success();
            }
            catch (Exception exc)
            {
                _logger.Error(exc.Message, exc);
                return ApiResponse.Warn(exc.Message);
            }
        }

        /// <summary>
        /// 获取用户积分
        /// </summary>
        /// <param name="page">页码（默认：1）</param>
        /// <param name="size">页大小（默认值：12）</param>
        /// <returns></returns>
        [HttpGet("points")]
        public async Task<ApiResponse<MoPoints>> Points(int page = 1, int size = 12)
        {
            if (!_rewardPointsSettings.Enabled)
                return ApiResponse<MoPoints>.Disable();

            var user = RegisterUser;
            if (user == null || !user.Active || user.Deleted)
                return ApiResponse<MoPoints>.Warn("用户不存在或被禁用");

            var data = await Task.Run(() =>
            {
                var model = new MoPoints();
                var command = new PagingFiltering
                {
                    PageNumber = page,
                    PageSize = size > 0 ? size : 10
                };
                var history = _userService.GetPointsHistory(user.Id, null, null, command.PageIndex, command.PageSize);
                model.Paging.Page = command.PageNumber;
                model.Paging.Size = command.PageSize;
                model.Paging.TotalPage = history.TotalPages;
                foreach (var rph in history)
                {
                    model.Items.Add(new MoPoints.RewardPointsHistoryModel()
                    {
                        Points = rph.Points,
                        Balance = rph.PointsBalance,
                        Msg = rph.Message,
                        Time = rph.CreateTime
                    });
                }
                int rewardPointsBalance = user.GetRewardPointsBalance();
                decimal rewardPointsAmount = _orderTotalCalculationService.ConvertRewardPointsToAmount((int)rewardPointsBalance);
                model.Balance = rewardPointsBalance;
                model.AmountVale = PriceFormatter.FormatPrice(rewardPointsAmount);
                return model;
            });

            return ApiResponse<MoPoints>.Success(data);
        }
        /// <summary>
        /// 上传用户头像
        /// </summary>
        /// <param name="uploadAvatar">头像json</param>
        /// <returns></returns>
        [ProducesResponseType(typeof(MoUploadAvatar), 200)]
        [HttpPost("uploadavatar")]
        public async Task<ApiResponse<MoAvatar>> UploadAvatar(MoUploadAvatar uploadAvatar)
        {
            var user = RegisterUser;
            if (user == null || !user.Active || user.Deleted)
                return ApiResponse<MoAvatar>.Warn("用户不存在或被禁用");

            try
            {
                var base64Str = uploadAvatar.base64Str;
                var data = await Task.Run(() =>
                  {
                      if (!string.IsNullOrEmpty(base64Str))
                      {
                          var mimeType = "image/jpeg";
                          if (base64Str.Contains("base64"))
                          {
                              if (base64Str.Contains("data:image/png;base64,"))
                              {
                                  mimeType = "image/png";
                                  base64Str = base64Str.Replace("data:image/png;base64,", "");
                              }
                              else if (base64Str.Contains("data:image/jpg;base64,") || base64Str.Contains("data:image/jpeg;base64,"))
                              {
                                  mimeType = "image/jpeg";
                                  base64Str = base64Str.Replace("data:image/jpeg;base64,", "").Replace("data:image/jpg;base64,", "");
                              }
                              else if (base64Str.Contains("data:image/gif;base64,"))
                              {
                                  mimeType = "image/gif";
                                  base64Str = base64Str.Replace("data:image/gif;base64,", "");
                              }
                          }
                          int avatarMaxSize = _userSettings.AvatarMaximumSizeBytes;
                          byte[] userPictureBinary = Convert.FromBase64String(base64Str);

                          if (user.AvatarPictureId > 0)
                              _pictureService.UpdatePicture(user.AvatarPictureId, userPictureBinary, mimeType, null, true);
                          else
                          {
                              var picture = _pictureService.InsertPicture(userPictureBinary, mimeType, null, true);
                              user.AvatarPictureId = picture.Id;
                          }
                          _userService.UpdateUser(user);
                      }
                      var model = new MoAvatar();
                      model.AvatarPictureId = user.AvatarPictureId;
                      model.Guid = user.UserGuid.ToString();
                      model.AvatarUrl = _pictureService.GetPictureUrl(user.AvatarPictureId, _mediaSettings.AvatarPictureSize, false);
                      return model;
                  });

                return ApiResponse<MoAvatar>.Success(data);
            }
            catch (Exception exc)
            {
                ModelState.AddModelError("", exc.Message);
            }

            return ApiResponse<MoAvatar>.Warn(ModelState.FirstMessage());
        }
        /// <summary>
        /// 我的邀请码
        /// </summary>
        /// <returns></returns>
        [HttpGet("myinvitecode")]
        public async Task<ApiResponse<MoInviteCode>> MyInviteCode()
        {
            var user = RegisterUser;
            if (user == null || !user.Active || user.Deleted)
                return ApiResponse<MoInviteCode>.Warn("用户不存在或被禁用");
            var data = await Task.Run(() =>
            {
                var model = new MoInviteCode()
                {
                    Guid = user.UserGuid.ToString(),
                    Code = user.Code,
                    Url = _webHelper.GetStoreLocation(false) + "?c=" + user.Code,
                };
                var imageName = string.Format("invite-{0}", user.Code);
                var bytes = _pictureService.GenerateQrcode(model.Url);
                if (!_pictureService.ExistsImageQrInFile(imageName))
                    _pictureService.SaveImageQrInFile(imageName, bytes);

                model.QrUrl = _pictureService.GetImageQrUrl(imageName);
                return model;
            });
            return ApiResponse<MoInviteCode>.Success(data);
        }
        /// <summary>
        /// 我的邀请用户
        /// </summary>
        /// <param name="page">页码（默认：1）</param>
        /// <param name="size">页大小（默认值：12）</param>
        /// <returns></returns>
        [HttpGet("myinvitees")]
        public async Task<ApiResponse<MoInvitees>> MyInvitees(int page = 1, int size = 12)
        {
            var user = RegisterUser;
            if (user == null || !user.Active || user.Deleted)
                return ApiResponse<MoInvitees>.Warn("用户不存在或被禁用");

            var data = await Task.Run(() =>
            {
                var model = new MoInvitees();
                var command = new PagingFiltering
                {
                    PageNumber = page,
                    PageSize = size > 0 ? size : 10
                };

                var invitees = _userService.GetInvitations(user.Id, command.PageNumber - 1, command.PageSize);
                model.Paging.Page = command.PageNumber;
                model.Paging.Size = command.PageSize;
                model.Paging.TotalPage = invitees.TotalPages;
                foreach (var item in invitees)
                {
                    model.Items.Add(new MoInvitees.MoInvitee()
                    {
                        Nickname = item.Nickname,
                        ImgUrl = _pictureService.GetPictureUrl(item.AvatarPictureId),
                        Phone = item.PhoneNumber,
                        Time = item.CreateTime
                    });
                }
                return model;
            });

            return ApiResponse<MoInvitees>.Success(data);
        }

        /// <summary>
        /// 检查店铺
        /// </summary>
        /// <returns></returns>
        [HttpPost("checkshop")]
        public async Task<ApiResponse> CheckShop(int Id)
        {
            var user = RegisterUser;
            if (user == null || !user.Active || user.Deleted)
                return ApiResponse<MoAvatar>.Warn("用户不存在或被禁用");

            try
            {
                user.ShopId = Id;
                _userService.UpdateUser(user);

                return ApiResponse.Success();
            }
            catch (Exception exc)
            {
                ModelState.AddModelError("", exc.Message);
            }
            return ApiResponse.Warn(ModelState.FirstMessage());
        }
    }
}
